﻿using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using NStore.Domain.Violations;

namespace NStore.Domain.Tests.Violations
{
    [TestClass]
    public class ProductValidatorTest
    {
        [TestMethod]
        public void ProductValidatorInstance_CallOnGetRuleViolationsWithoutRuleViolations_ReturnEmptyList()
        {
            ProductValidator productValidator = new ProductValidator(new List<Product>());

            Product product = new Product { Name = "Name", Price = 2.03f, Validator = productValidator };

            Assert.AreEqual(0, productValidator.GetRuleViolations(product).Count());
        }

        [TestMethod]
        public void ProductValidatorInstance_CallOnGetRuleViolationsWithNamePropertyViolation_ReturnViolations()
        {
            ProductValidator productValidator = new ProductValidator(new List<Product>());
            Product product = new Product { Validator = productValidator };

            RuleViolation ruleViolation = productValidator.GetRuleViolations(product).First(r => r.PropertyName.Equals("Name"));
            
            Assert.AreEqual("The Name field is required", ruleViolation.ErrorMessage);
            Assert.AreEqual("Name", ruleViolation.PropertyName);
        }

        [TestMethod]
        public void ProductValidatorInstance_CallOnGetRuleViolationsWithDuplicateName_ReturnViolations()
        {
            Product stubProduct2 = new Product();
            stubProduct2.Name = "Name";
            
            ProductValidator productValidator = new ProductValidator(new List<Product> {stubProduct2});
            Product product = new Product { Name = "Name", Validator = productValidator};
            RuleViolation ruleViolation = productValidator.GetRuleViolations(product).First(r => r.PropertyName.Equals("Name"));

            Assert.IsTrue(ruleViolation.ErrorMessage.Contains("Name duplicated in product with id :"));
            Assert.AreEqual("Name", ruleViolation.PropertyName);
        }

        [TestMethod]
        public void ProductValidatorInstance_CallOnGetRuleViolationsWithPricePropertyViolation_ReturnViolations()
        {
            ProductValidator productValidator = new ProductValidator(new List<Product>());
            Product product = new Product { Validator = productValidator };

            RuleViolation ruleViolation = productValidator.GetRuleViolations(product).First(r => r.PropertyName.Equals("Price"));

            Assert.AreEqual("The Price field should have non zero value", ruleViolation.ErrorMessage);
            Assert.AreEqual("Price", ruleViolation.PropertyName);
        }
    }
}
